﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace PexTestsFormatter
{
    class Program
    {
        static HashSet<String> usingStmts = new HashSet<String>();
        static List<String> allMethodsToInvoke = new List<String>();

        static void Main(string[] args)
        {
            try
            {
                String directoryName = args[0];
                processDir(directoryName);

                //Output all classes and methods
                StreamWriter swOutput = new StreamWriter(new FileStream(directoryName + "\\Consolidated.cs", FileMode.Create, FileAccess.Write));

                foreach (String usingStmt in usingStmts)
                    swOutput.WriteLine(usingStmt);

                swOutput.WriteLine("public class ConsolidatedPexTest");
                swOutput.WriteLine("{");
                swOutput.WriteLine("\tpublic static int Main()");
                swOutput.WriteLine("\t{");
                foreach (String methodName in allMethodsToInvoke)
                {
                    swOutput.WriteLine("\t\t try {");
                    swOutput.WriteLine("\t\t\t" + methodName);
                    swOutput.WriteLine("\t\t } catch(System.Exception) {}");
                    swOutput.WriteLine("");
                }

                swOutput.WriteLine("\t\treturn 0;");
                swOutput.WriteLine("\t}");
                swOutput.WriteLine("}");
                swOutput.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }


        static void processDir(String dirName)
        {
            string[] filePaths = Directory.GetFiles(dirName);
            
            foreach (string filePathEntry in filePaths)
            {
                if(filePathEntry.Equals(".") || filePathEntry.Equals(".."))
                    continue;

                if (Directory.Exists(filePathEntry))
                    processDir(filePathEntry);

                if (!filePathEntry.EndsWith(".g.cs"))
                    continue;

                StreamReader tr = new StreamReader(filePathEntry);
                String inpStr;
                String namespaceName = "";
                String className = "";
                String methodName = "";

                while ((inpStr = tr.ReadLine()) != null)
                {
                    inpStr = inpStr.Trim();
                    if (inpStr.StartsWith("using"))
                        usingStmts.Add(inpStr);

                    if (inpStr.StartsWith("namespace "))
                    {
                        namespaceName = inpStr.Substring(10, inpStr.Length - 10);
                        usingStmts.Add("using " + namespaceName + ";");
                    }
                    
                    if (inpStr.StartsWith("public partial class "))
                        className = inpStr.Substring(21, inpStr.Length - 21);

                    if (inpStr.StartsWith("public void ")) {
                        methodName = inpStr.Substring(12, inpStr.Length - 12);
                        allMethodsToInvoke.Add("new " + className + "()." + methodName + ";");
                    }                               
                }
                tr.Close();

            }

            //Process directories in this
            foreach (String dirEntry in Directory.GetDirectories(dirName))
            {
                processDir(dirEntry);
            }
        }
    }
}
